package org.origin.ferret.system.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.origin.centre.model.base.XPage;
import org.origin.centre.model.consts.XConst;
import org.origin.centre.model.dto.XDeleteByIdDto;
import org.origin.centre.model.dto.XQueryByIdDto;
import org.origin.centre.model.dto.XUpdateByIdDto;
import org.origin.centre.model.enums.XUsable;
import org.origin.centre.model.vo.XPageVo;
import org.origin.ferret.system.mapper.SysDictMapper;
import org.origin.ferret.system.mapstruct.SysDictMapstruct;
import org.origin.ferret.system.model.dto.dict.*;
import org.origin.ferret.system.model.entity.SysDictEntity;
import org.origin.ferret.system.model.vo.dict.SysDictVo;
import org.origin.ferret.system.service.SysDictService;
import org.springframework.stereotype.Service;

import java.util.Objects;

import static org.origin.ferret.system.model.entity.table.SysDictEntityTableDef.SYS_DICT_ENTITY;

/**
 * 系统字典-服务
 *
 * @author ferret
 * @version 2024-05-08
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysDictServiceImpl implements SysDictService {
    private final SysDictMapper dictMapper;
    private final SysDictMapstruct dictMapstruct;

    @Override
    public XPageVo<SysDictVo> page(XPage<SysDictPageDto> pageDto) {
        SysDictPageDto params = pageDto.getParams();
        Page<SysDictEntity> pagePojo = this.dictMapper
                .paginate(pageDto.getPageNum(), pageDto.getPageSize(), QueryWrapper.create()
                        .where(SYS_DICT_ENTITY.PARENT_ID.eq(XConst.DICT_ID))
                        .and(SYS_DICT_ENTITY.NAME.like(params.getName(), StringUtils::isNotBlank))
                        .and(SYS_DICT_ENTITY.TYPE.like(params.getType(), StringUtils::isNotBlank))
                        .and(SYS_DICT_ENTITY.STATUS.eq(params.getStatus(), Objects::nonNull))
                        .orderBy(SYS_DICT_ENTITY.STATUS.asc())
                        .orderBy(SYS_DICT_ENTITY.CREATE_TIME.desc())
                        .orderBy(SYS_DICT_ENTITY.ID.desc())
                );
        return new XPageVo<SysDictVo>()
                .of(pageDto, pagePojo.getTotalRow(),
                        pagePojo.getRecords(), this.dictMapstruct::toVo);
    }

    @Override
    public SysDictVo query(XQueryByIdDto queryDto) {
        SysDictEntity entity = this.dictMapper.selectOneById(queryDto.getId());
        return this.dictMapstruct.toVo(entity);
    }

    @Override
    public Boolean insert(SysDictInsertDto insertDto) {
        SysDictEntity entity = this.dictMapstruct.toEntity(insertDto);
        entity.setParentId(XConst.DICT_ID);
        entity.setStatus(XUsable.USABLE.getCode());
        entity.preInsert();
        int insertNum = this.dictMapper.insert(entity);
        return insertNum > 0;
    }

    @Override
    public Boolean update(SysDictUpdateDto updateDto) {
        SysDictEntity entity = this.dictMapstruct.toEntity(updateDto);
        entity.setStatus(null);
        entity.setParentId(null);
        entity.preUpdate();
        int updateNum = this.dictMapper.update(entity);
        return updateNum > 0;
    }

    @Override
    public Boolean delete(XDeleteByIdDto deleteDto) {
        int updateNum = this.dictMapper.deleteById(deleteDto.longId());
        return updateNum > 0;
    }

    @Override
    public Boolean valid(XUpdateByIdDto updateDto) {
        SysDictEntity entity = new SysDictEntity();
        entity.setId(updateDto.longId());
        entity.setStatus(XUsable.USABLE.getCode());
        entity.preUpdate();
        int updateNum = this.dictMapper.update(entity);
        return updateNum > 0;
    }

    @Override
    public Boolean invalid(XUpdateByIdDto updateDto) {
        SysDictEntity entity = new SysDictEntity();
        entity.setId(updateDto.longId());
        entity.setStatus(XUsable.DISABLE.getCode());
        entity.preUpdate();
        int updateNum = this.dictMapper.update(entity);
        return updateNum > 0;
    }

    @Override
    public XPageVo<SysDictVo> childrenPage(XPage<SysDictPageDto> pageDto) {
        SysDictPageDto params = pageDto.getParams();
        Page<SysDictEntity> pagePojo = this.dictMapper
                .paginate(pageDto.getPageNum(), pageDto.getPageSize(), QueryWrapper.create()
                        .where(SYS_DICT_ENTITY.PARENT_ID.eq(XConst.DICT_ID))
                        .and(SYS_DICT_ENTITY.NAME.like(params.getName(), StringUtils::isNotBlank))
                        .and(SYS_DICT_ENTITY.TYPE.like(params.getType(), StringUtils::isNotBlank))
                        .and(SYS_DICT_ENTITY.STATUS.eq(params.getStatus(), Objects::nonNull))
                        .orderBy(SYS_DICT_ENTITY.STATUS.asc())
                        .orderBy(SYS_DICT_ENTITY.CREATE_TIME.desc())
                        .orderBy(SYS_DICT_ENTITY.ID.desc())
                );
        return new XPageVo<SysDictVo>()
                .of(pageDto, pagePojo.getTotalRow(),
                        pagePojo.getRecords(), this.dictMapstruct::toVo);
    }

    @Override
    public Boolean childrenInsert(SysDictChildrenInsertDto insertDto) {
        SysDictEntity entity = this.dictMapstruct.toEntity(insertDto);
        entity.setParentId(XConst.DICT_ID);
        entity.setStatus(XUsable.USABLE.getCode());
        entity.preInsert();
        int insertNum = this.dictMapper.insert(entity);
        return insertNum > 0;
    }

    @Override
    public Boolean childrenUpdate(SysDictChildrenUpdateDto updateDto) {
        SysDictEntity entity = this.dictMapstruct.toEntity(updateDto);
        entity.setStatus(null);
        entity.setParentId(null);
        entity.preUpdate();
        int updateNum = this.dictMapper.update(entity);
        return updateNum > 0;
    }

    @Override
    public Boolean childrenDelete(XDeleteByIdDto deleteDto) {
        int updateNum = this.dictMapper.deleteById(deleteDto.longId());
        return updateNum > 0;
    }

    @Override
    public Boolean childrenValid(XUpdateByIdDto updateDto) {
        SysDictEntity entity = new SysDictEntity();
        entity.setId(updateDto.longId());
        entity.setStatus(XUsable.USABLE.getCode());
        entity.preUpdate();
        int updateNum = this.dictMapper.update(entity);
        return updateNum > 0;
    }

    @Override
    public Boolean childrenInvalid(XUpdateByIdDto updateDto) {
        SysDictEntity entity = new SysDictEntity();
        entity.setId(updateDto.longId());
        entity.setStatus(XUsable.DISABLE.getCode());
        entity.preUpdate();
        int updateNum = this.dictMapper.update(entity);
        return updateNum > 0;
    }

    @Override
    public Boolean childrenDefault(XUpdateByIdDto updateDto) {
        SysDictEntity entity = new SysDictEntity();
        entity.setId(updateDto.longId());
        entity.setStatus(XUsable.DISABLE.getCode());
        entity.preUpdate();
        int updateNum = this.dictMapper.update(entity);
        return updateNum > 0;
    }

    @Override
    public XPageVo<SysDictVo> configPage(XPage<SysDictPageDto> pageDto) {
        SysDictPageDto params = pageDto.getParams();
        Page<SysDictEntity> pagePojo = this.dictMapper
                .paginate(pageDto.getPageNum(), pageDto.getPageSize(), QueryWrapper.create()
                        .where(SYS_DICT_ENTITY.PARENT_ID.eq(XConst.CONFIG_ID))
                        .and(SYS_DICT_ENTITY.NAME.like(params.getName(), StringUtils::isNotBlank))
                        .and(SYS_DICT_ENTITY.TYPE.like(params.getType(), StringUtils::isNotBlank))
                        .and(SYS_DICT_ENTITY.STATUS.eq(params.getStatus(), Objects::nonNull))
                        .orderBy(SYS_DICT_ENTITY.STATUS.asc())
                        .orderBy(SYS_DICT_ENTITY.CREATE_TIME.desc())
                        .orderBy(SYS_DICT_ENTITY.ID.desc())
                );
        return new XPageVo<SysDictVo>()
                .of(pageDto, pagePojo.getTotalRow(),
                        pagePojo.getRecords(), this.dictMapstruct::toVo);
    }

}
